import threading
import gevent
import time


class MyThread(threading.Thread):
    def __init__(self, call_func):
        super(MyThread, self).__init__()
        self.call_func = call_func

    def run(self):
        self.call_func()


class DaemonThread:
    def __init__(self):
        super(DaemonThread, self).__init__()
        self.task_queue = []
        self.force_exit = False
        self.th1 = MyThread(self.run_daemonthreads)
        self.spawns = []

    def add_task(self, call_func, *args):
        self.task_queue.append((call_func, self, args))

    def run(self):
        self.th1.start()

    def run_daemonthreads(self):
        self.spawns = []
        task_count = len(self.task_queue)
        for i in range(task_count):
            f, q, p = self.task_queue[i]
            self.spawns.append(gevent.spawn(f, q, *p))
        gevent.joinall(self.spawns)
        print("daemon thread stop")

    def shutdown(self):
        self.force_exit = True


DAEMON_QUEUE = DaemonThread()

if __name__ == "__main__":
    def task1(queue, a, b):
        while True:
            if queue.force_exit:
                break
            print("task1", a, b)
            gevent.sleep(1)

    def task2(queue):
        while True:
            if queue.force_exit:
                break
            print("task2")
            gevent.sleep(1)

    def task3(queue):
        while True:
            if queue.force_exit:
                break
            print("task3")
            gevent.sleep(1)

    DAEMON_QUEUE.add_task(task1, 3, 4)
    DAEMON_QUEUE.add_task(task2)
    DAEMON_QUEUE.add_task(task3)
    DAEMON_QUEUE.run()

    time.sleep(20)
    DAEMON_QUEUE.shutdown()
